var pd = require('pd'),
    ee = require('eventemitter-light'),
    url = require('url'),
    gzip = require('./gzip.js'),
    repeat = require('./repeat.js');

var defaults = {
    'autopage': false,
    'pagesize': 50,
    'connection.host': 'api.stackexchange.com'
};
    
module.exports = {
    request: function () {
        var page = 1,
            items = [],
            client = this._client,
            connection = pd.extend({}, this._connection);

        client.on('complete', response.bind(this));
        get(page);
        
        function get(page) {
            connection.query.page = page;

            client.request(url.parse(url.format(connection)));
        }
        
        function response(wrapper) {
            wrapper = JSON.parse(wrapper);
        
            if (!wrapper.error_id) {
                items.push.apply(items, wrapper.items);
                
                if (this._options.autopage && wrapper.has_more) {
                    get(++page);
                } else {
                    client.removeListener('complete', response);
                    this.emit('complete', items);
                    this.next();
                }
            } else {
                client.removeListener('complete', response);
                this.emit('error', {
                    id: wrapper.error_id,
                    name: wrapper.error_name,
                    message: wrapper.error_message
                });
            }
        }
    },
    constructor: function constructor(route, options) {
        pd.bindAll(this);
        pd.extend(this, ee, repeat, { constructor: constructor });
        ee.constructor.call(this);
        repeat.constructor.call(this, this.request);
        
        this._options = pd.extend({}, defaults, options || {});
        this._client = Object.create(gzip).constructor();
        this._client.on('error', (function () {
            var args = Array.prototype.slice.call(arguments);
            
            args.unshift('error');
            this.emit.apply(this, args);
        }).bind(this));
        
        var parsed = url.parse(route, true);
        
        if (!parsed.pathname) {
            throw new Error("options.path is invalid");
        }
        
        if (parsed.search) {
            delete parsed.search;
        }
        
        if (!parsed.hostname) {
            parsed.hostname = defaults['connection.host'];
        }
        
        parsed.protocol = 'http:';
        parsed.query = parsed.query || {};
        parsed.query.pagesize = parsed.query.pagesize || defaults.pagesize;
        
        this._connection = parsed;
        
        return this;
    }
}